﻿/*Copyright (C) 2010-2012 RAAFCOM B.V. All rights reserved.

This file is part of Velsto and may be used under the terms of:
The GNU General Public License version 3 or higher, as published by
the Free Software Foundation.

This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.*/
/* 
* Application  : Velsto
* Class        : FormMain
* 04/06/2010-  : M.A.van Ravesteijn (Raafcom)
*   02/12/2011   Initial version v1.0
* 09/05/2012-  : M.A.van Ravesteijn (Raafcom)
*   21/05/2012   Version 1.1(Well tied avz map, save map as xyz, use Temp folder).
* 14/06/2012-  : M.A.van Ravesteijn (Raafcom)
*   30/10/2012 : Version 1.2 (Well residual workflow)
* 
* Class for Main form Velsto
* 
* Main form for Application Velsto with Subforms FormSingleresults and 
* FormMap(MapWindow form). Currently (v1.0) 2 tabs and DataGridView for
* LayerParameters.
* Use is made of CommandLineProcess classes for spawning Command line threads.
* Use is made of DataGridViewDisableButtonCell and Column classes (from Microsoft)
* Velsto(Velocity Stochastics) is a program around the Velsim Simulation tool
* 
*/
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using twComps;

namespace Velsto
{
    public delegate void SelectDelegate(MapWinGIS.Shapefile sf1, SimulationEntity se2);

    public partial class FormMain : Form
    {
        delegate void call_sireCallback();
        delegate void call_mapCallback();
        string gridFile = "";
        string gridType = "";
        private SimulationEntity se;
        private LayerparamsDataTable lpDt = new LayerparamsDataTable();
        private ArrayList alVtypes = new ArrayList();
        private Dictionary<Point, double> dictkb2d = new Dictionary<Point, double>();
        private Dictionary<Point, double> dictMapA = new Dictionary<Point, double>();
        private Dictionary<Point, double> dictMapB = new Dictionary<Point, double>();
        private SortedList<double,double> slmapforhist;        
        private Dictionary<string, string> props = new Dictionary<string, string>();
        private CommandLineProcess cmd = new CommandLineProcess();
        private MapWinGIS.Shapefile sf = new MapWinGIS.Shapefile();
        private bool resWorkflow = false;
        private cBack cbgen;
        private cBack cbgen2;
        private double timesim;
        private bool fileOpening = false;

        
               
        public FormMain()
        {
            InitializeComponent();
            // To report progress from the background worker we need to set this property
            backgroundWorker1.WorkerReportsProgress = true;
            // This event will be raised on the worker thread when the worker starts
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            // This event will be raised when we call ReportProgress
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            // To report progress from the background worker we need to set this property
            backgroundWorker2.WorkerReportsProgress = true;
            // This event will be raised on the worker thread when the worker starts
            backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
            // This event will be raised when we call ReportProgress
            backgroundWorker2.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker2_ProgressChanged);
    
            this.Text = "Velsto 1.2.1";
            ToolTip forButton = new ToolTip();
            forButton.SetToolTip(pictureBox1, "Create file in Notepad\nlines of format Layernr x y(e.g.\"1 23456.1 12345.2\"");
            forButton.AutomaticDelay = 2000;
            forButton.ShowAlways = true;
            forButton.ToolTipIcon = ToolTipIcon.Info;
            forButton.InitialDelay = 1;

            /*ToolTip forButton2 = new ToolTip();
            forButton2.SetToolTip(well_tied_file_pictureBox, "Create file in Notepad\nlines of format Layernr x y markerdepth(tvd msl/slr))(e.g.\"1 23456.1 12345.2 3012\"");
            forButton2.AutomaticDelay = 2000;
            forButton2.ShowAlways = true;
            forButton2.ToolTipIcon = ToolTipIcon.Info;
            forButton2.InitialDelay = 1;*/

            mapTypeComboBox.Items.Add("TWT");
            mapTypeComboBox.Items.Add("\u03c3TWT");
            mapTypeComboBox.Items.Add("V");
            mapTypeComboBox.Items.Add("\u03c3V");
            mapTypeComboBox.Items.Add("Z");
            mapTypeComboBox.Items.Add("\u03c3Z");

            griddingTypeCB.Items.Add("Triangulation");
            griddingTypeCB.Items.Add("Nearest neighbour");
            griddingTypeCB.Items.Add("Continuous curvature");

            
        
            
            
            se = new SimulationEntity();
            se.Gc_GridGrid = true;
            se.TempFolderpath = Path.GetTempPath();
            //MessageBox.Show(se.TempFolderpath);
/*           if (!File.Exists(Constants.PROPSFILE))
            {
                MessageBox.Show("Cannot find Properties File " + Constants.PROPSFILE +
                                "\r\nContact Application Support");
                openToolStripMenuItem.Enabled = false;
                newToolStripMenuItem.Enabled = false;
            }
            else
            {
                PropertiesFile pf = new PropertiesFile();
                props = (Dictionary<string, string>)pf.getProps(Constants.PROPSFILE);
                // Check dustexe
                if (!File.Exists(props["velsimexe"]))
                {
                    MessageBox.Show("parameter velsimexe in file "+Constants.PROPSFILE+
                                    "\r\nnot properly set,should point to Velsim.exe "+
                                    "\r\ne.g. velsimexe=C:\\Apps\\Dustin\\Velsim.exe"+
                                    "\r\nContact Application Support");
                    openToolStripMenuItem.Enabled = false;
                    newToolStripMenuItem.Enabled = false;
                }
            }*/
            setuplpDgv();
            // set Layernr out
            this.label2.Visible = false;
            this.nrLayersTextBox.Visible = false;
            // initialise other components
            this.projNameTextBox.Enabled = false;
            this.resultFolderTextBox.Enabled = false;
            this.addLayerAboveButton.Enabled = false;
            this.addLayerBelowButton.Enabled = false;
            this.deleteLayerButton.Enabled = false;
            this.runButton.Enabled = false;
            this.saveButton.Enabled = false;
            this.joinUnequalButton.Enabled = false;
            this.showMapButton.Enabled = false;
            this.bu_gridinfo.Enabled = false;
            this.resultFolderButton.Enabled = false;
            this.wellLayerFileButton.Enabled = false;
            this.showmapfilewell_Button.Enabled = false;
            this.Well_residuals_workflow_button.Enabled = false;
            this.outputToolStripMenuItem.Enabled = false;
            this.pointSelButton.Enabled = false;
            this.inputXYZfileSelectbutton.Enabled = true;
            this.inputXYZfileViewButton.Enabled = true;
            this.outputXYZbutton.Enabled = true;
            this.outputXYZviewButton.Enabled = true;
            this.selGridRefButton.Enabled = true;
            this.griddingTypeCB.Enabled = true;
            this.runGriddingButton.Enabled = true;
            this.gmtlogButton.Enabled = true;
            
            searchRadiuslabel.Hide();
            pBar1.Hide();
            pBar2.Hide();
            pBar3.Hide();
            searchRadiusTextBox.Hide();
            saveToolStripMenuItem.Enabled = false;
            saveAsToolStripMenuItem.Enabled = false;
            
            lb_rwf_moreinfo.Visible = false;
            lb_wellunc_moreinfo.Visible = false;
            lb_gen_moreinfo.Visible = false;
            
        }

        public FormMain(MapWinGIS.Shapefile sf1, SimulationEntity se2)
        {
            InitializeComponent();
            se = new SimulationEntity(se2);
            sf = sf1;
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            ToolTip tt1 = new ToolTip();
            tt1.SetToolTip(projNameTextBox, "Projectname (without spaces and backslashes)");
            ToolTip tt2 = new ToolTip();
            tt2.SetToolTip(nrLayersTextBox, "nr. layers for simulation (see Simulation tab)");
            ToolTip tt3 = new ToolTip();
            tt3.SetToolTip(resultFolderButton, "Folder to store results of simulation(z and stdev)");
            ToolTip tt4 = new ToolTip();
            tt4.SetToolTip(mapTypeComboBox, "Grid type");
            ToolTip tt5 = new ToolTip();
            tt5.SetToolTip(maplayCb, "Grid name");
            ToolTip tt6 = new ToolTip();
            tt6.SetToolTip(joinUnequalButton, "Only common area(i.e.area overlapped by all grids)\nis included in simulation grid");
            ToolTip tt7 = new ToolTip();
            tt7.SetToolTip(xSelTextBox, "Point to search nearest grid point for single point simulation");
            ToolTip tt8 = new ToolTip();
            tt8.SetToolTip(ySelTextBox, "Point to search nearest grid point for single point simulation");
            ToolTip tt9 = new ToolTip();
            tt9.SetToolTip(runButton, "Run simulation");
            ToolTip tt10 = new ToolTip();
            tt10.SetToolTip(saveButton, "Save project file(.vsw file)");
            ToolTip tt11 = new ToolTip();
            tt11.SetToolTip(wellTvdMarkerFileButton, "Input file with tvd markers, format (x y marker wellname(no spaces in wellname)) or\nmarker file saved previously in workflow\nFile maybe selected alternatively in workflow screen");
            tt11.AutomaticDelay = 2000;
            tt11.InitialDelay = 1;
            ToolTip tt12 = new ToolTip();
            tt12.SetToolTip(well_tied_layer_comboboxb, "Raw depth grid : result from simulation");

            ToolTip tt15 = new ToolTip();
            tt15.SetToolTip(gmtlogButton, "Log with messages from GMT run");
        }

        

        #region Toolstrip and related buttons

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (se.VswFilename != null)
            {
                savefileDialog();
            }
            fileOpening = true;
            OpenFileDialog of1 = new OpenFileDialog();
            of1.Filter = "Velsto project files|*.vsw";
            //of1.Filter = "Windows velsto files (.vsw)";
            of1.FilterIndex = 1;
            var mb_ret = of1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    fileOpening = false;
                    break;
                default:
                    VswFile ds = new VswFile();
                    se =
                        new SimulationEntity(ds.readVswfile(of1.FileName));
                    se.TempFolderpath = Path.GetTempPath();
                    se.VswFilename = of1.FileName;                   
                    if (se.ErrorMessage != null)
                    {
                        MessageBox.Show(this, se.ErrorMessage, "**Error**",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    se.GridTWTdevinseconds = false;
                    projNameTextBox.Text = se.ProjectName;
                    nrLayersTextBox.Text = Convert.ToString(se.NrLayers);

                    setLayerComboboxes();
            
                    xSelTextBox.Text = "0.0";
                    ySelTextBox.Text = "0.0";
                    xTextBox.Text = "";
                    yTextBox.Text = "";
                    simulnr_textBox.Text = "500";
                    rangeTextBox.Text = "2000";
                    se.Kb2dRange = 2000.0;
                    wellLayerFileTextBox.Text = "";
                    wellTvdMarkerTextBox.Text = "";
                    se.WellLayerFile = "";
                    resultFolderTextBox.Text = se.ResultFolderpath;
                    lpDt.Clear();
                    // Fill DataTable
                    lpDt.fillLayerparamsDataTable(se);

                    
                    // Set DataGridView Combobox and Button values somehow they are columns 0-4
                    for (int i = 0; i < lpDgv.Rows.Count; i++)
                    {
                        lpDgv.Rows[i].Height = 20;
                        ((DataGridViewComboBoxCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VSELCOMBO])).Value =
                         alVtypes[((LayerparamsEntity)se.AlLayerParams[i]).V0vintOption];
                        ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).Value = Constants.TWTBUTTONTEXT;
                        ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).Value = Constants.VBUTTONTEXT;
                        ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).Value = Constants.VDEVBUTTONTEXT;
                        ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).Value = Constants.TWTDEVBUTTONTEXT;
                    }
                    for (int i = 0; i < lpDgv.Rows.Count; i++)
                    {
                        ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).ToolTipText = "Get grid (xyz file)";
                    }
                    simulOptionBox.SelectedIndex = se.SimulOption - 1;                   
                    mapTypeComboBox.SelectedIndex = se.MapType - 1;
                    griddingTypeCB.SelectedIndex = 0;
                    this.projNameTextBox.Enabled = true;
                    this.addLayerAboveButton.Enabled = true;
                    this.addLayerBelowButton.Enabled = true;
                    this.deleteLayerButton.Enabled = true;
                    this.runButton.Enabled = true;
                    this.saveButton.Enabled = true;
                    this.joinUnequalButton.Enabled = true;
                    this.showMapButton.Enabled = true;
                    this.bu_gridinfo.Enabled = true;
                    this.resultFolderButton.Enabled = true;
                    this.wellLayerFileButton.Enabled = true;
                    this.showmapfilewell_Button.Enabled = true;
                    this.Well_residuals_workflow_button.Enabled = true;
                    this.outputToolStripMenuItem.Enabled = true;
                    this.pointSelButton.Enabled = true;
                    this.inputXYZfileSelectbutton.Enabled = true;
                    this.inputXYZfileViewButton.Enabled = true;
                    this.outputXYZbutton.Enabled = true;
                    this.outputXYZviewButton.Enabled = true;
                    this.selGridRefButton.Enabled = true;
                    this.griddingTypeCB.Enabled = true;
                    this.runGriddingButton.Enabled = true;
                    this.gmtlogButton.Enabled = true;
                    searchRadiuslabel.Hide();
                    this.Text = "Velsto " + se.VswFilename;
                    saveToolStripMenuItem.Enabled = true;
                    saveAsToolStripMenuItem.Enabled = true;
                    se.SavedFile = true;
                    se.GridsJoined = false;
                    se.SingleSelected = false;
                    fileOpening = false;
                    break;
            }
        }

        private void setLayerComboboxes()
        {
            // Initiate Layernr comboboxes
            maplayCb.Items.Clear();
            for (int i = 0; i < se.NrLayers; i++)
            {
                if (se.AlLayername[i].Equals(""))
                {
                    maplayCb.Items.Add((i + 1).ToString());
                }
                else
                {
                    maplayCb.Items.Add(se.AlLayername[i]);
                }
            }
            maplayCb.SelectedIndex = se.NrLayers - 1;
            se.MapSimLayernr = se.NrLayers;
            maplayerwell_ComboBox.Items.Clear();
            for (int i = 0; i < se.NrLayers; i++)
            {
                if (se.AlLayername[i].Equals(""))
                {
                    maplayerwell_ComboBox.Items.Add((i + 1).ToString());
                }
                else
                {
                    maplayerwell_ComboBox.Items.Add(se.AlLayername[i]);
                }
            }
            se.MapALayernr = se.NrLayers;
            maplayerwell_ComboBox.SelectedIndex = se.NrLayers - 1;
            well_tied_layer_comboboxb.Items.Clear();
            for (int i = 0; i < se.NrLayers; i++)
            {
                if (se.AlLayername[i].Equals(""))
                {
                    well_tied_layer_comboboxb.Items.Add((i + 1).ToString());
                }
                else
                {
                    well_tied_layer_comboboxb.Items.Add(se.AlLayername[i]);
                }
            }
            se.MapBLayernr = se.NrLayers;
            well_tied_layer_comboboxb.SelectedIndex = se.NrLayers - 1;
            return;        
        }

        

        



        
        

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (se.NewFile)
            {
                SaveFileDialog sf1 = new SaveFileDialog();
                sf1.Filter = "Velsto project files|*.vsw";
                sf1.FilterIndex = 1;
                var mb_ret = sf1.ShowDialog();
                VswFile ds = new VswFile();
                switch (mb_ret)
                {
                    case DialogResult.Cancel:
                        break;
                    default:
                        se = lpDt.updateSimulationEntity(se);
                        se.ErrorMessage = ds.saveVswfile(se, sf1.FileName);
                        if (se.ErrorMessage != null)
                        {
                            MessageBox.Show(this, se.ErrorMessage, "Error Occurred",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                        {
                            se.NewFile = false;
                            se.SavedFile = true;
                            se.VswFilename = sf1.FileName;
                            this.Text = "Velsto " + se.VswFilename;
                        }
                        break;
                }
            }
            else
            {
                se = lpDt.updateSimulationEntity(se);
                VswFile ds = new VswFile();
                se.ErrorMessage = ds.saveVswfile(se, se.VswFilename);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(this, se.ErrorMessage, "Error Occurred",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    se.NewFile = false;
                    se.SavedFile = true;
                    this.Text = "Velsto " + se.VswFilename;
                    //MessageBox.Show("se Saved to " + se.VswFilename);
                }

            }
        }

        // Method for Save As dialog (Menubaroption File->Save As)
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sf1 = new SaveFileDialog();
            sf1.Filter = "Velsto project files|*.vsw";
            sf1.FilterIndex = 1;
            var mb_ret = sf1.ShowDialog();
            VswFile ds = new VswFile();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    // Save File
                    se = lpDt.updateSimulationEntity(se);
                    se.ErrorMessage = ds.saveVswfile(se, sf1.FileName);
                    if (se.ErrorMessage != null)
                    {
                        MessageBox.Show(this, se.ErrorMessage, "Error Occurred",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        se.SavedFile = true;
                        se.VswFilename = sf1.FileName;
                        this.Text = "Velsto " + se.VswFilename;
                    }
                    break;
            }
            
        }

        // Method for new blank Simulationentity (Menubaroption File->New)
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            savefileDialog();
            se = new SimulationEntity();
            se.TempFolderpath = Path.GetTempPath();
            projNameTextBox.Text = se.ProjectName;
            nrLayersTextBox.Text = Convert.ToString(se.NrLayers);

            setLayerComboboxes();
            
            se.MapLayernr = se.NrLayers;
            mapTypeComboBox.SelectedIndex = se.MapType - 1;
            griddingTypeCB.SelectedIndex = 0;                    
            resultFolderTextBox.Text = "";
            se.GridTWTdevinseconds = false;
            xSelTextBox.Text = "0.0";
            ySelTextBox.Text = "0.0";
            xTextBox.Text = "";
            yTextBox.Text = "";
            simulnr_textBox.Text = "500";
            rangeTextBox.Text = "2000";
            se.Kb2dRange = 2000.0;
            wellLayerFileTextBox.Text = "";
            se.WellLayerFile = "";
            lpDt.Clear();
            lpDt.fillLayerparamsDataTable(se); 
            // Set DataGridView Combobox and Button values somehow they are columns 0-4
            setComboButtonCellTexts();
            simulOptionBox.SelectedIndex = se.SimulOption - 1;
            this.projNameTextBox.Enabled = true;
            this.addLayerAboveButton.Enabled = true;
            this.addLayerBelowButton.Enabled = true;
            this.deleteLayerButton.Enabled = true;
            this.runButton.Enabled = true;
            this.saveButton.Enabled = true;
            this.joinUnequalButton.Enabled = true;
            this.showMapButton.Enabled = true;
            this.bu_gridinfo.Enabled = true;
            this.resultFolderButton.Enabled = true;
            this.wellLayerFileButton.Enabled = true;
            this.showmapfilewell_Button.Enabled = true;
            this.Well_residuals_workflow_button.Enabled = true;
            this.outputToolStripMenuItem.Enabled = true;
            this.pointSelButton.Enabled = true;
            this.saveToolStripMenuItem.Enabled = true;
            this.saveAsToolStripMenuItem.Enabled = true;
            this.inputXYZfileSelectbutton.Enabled = true;
            this.inputXYZfileViewButton.Enabled = true;
            this.outputXYZbutton.Enabled = true;
            this.outputXYZviewButton.Enabled = true;
            this.selGridRefButton.Enabled = true;
            this.griddingTypeCB.Enabled = true;
            this.runGriddingButton.Enabled = true;
            this.Text = "Velsto New file";
            this.gmtlogButton.Enabled = true;                           
            se.SavedFile = false;
            se.GridsJoined = false;
            se.SingleSelected = false;
            se.NewFile = true;
        }


        // Method to set text in Buttons in Data Grid View
        private void setComboButtonCellTexts()
        {
            for (int i = 0; i < lpDgv.Rows.Count; i++)
            {
                lpDgv.Rows[i].Height = 20;
                ((DataGridViewComboBoxCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VSELCOMBO])).Value =
                 alVtypes[0];
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).Value = Constants.TWTBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).Value = Constants.VBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).Value = Constants.VDEVBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).Value = Constants.TWTDEVBUTTONTEXT;
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close(); 
        }
        
        // Method with code for Save file Dialog used when File->New or File->Open
        // is selected
        private void savefileDialog()
        {    
            if (se.SavedFile)
            {
                return;
            }
            else
            {
                var mb_ret = MessageBox.Show(this,
                    "File not Saved, do you want to Save?",
                    "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                switch (mb_ret)
                {
                    case DialogResult.Yes:
                        if (se.NewFile)
                        {
                            SaveFileDialog sf1 = new SaveFileDialog();
                            sf1.Filter = "Velsto project files|*.vsw";
                            sf1.FilterIndex = 1;
                            var mb_ret2 = sf1.ShowDialog();
                            VswFile ds = new VswFile();
                            switch (mb_ret2)
                            {
                                case DialogResult.Cancel:
                                    break;
                                default:
                                    se = lpDt.updateSimulationEntity(se);
                                    ds.saveVswfile(se, sf1.FileName);
                                    se.SavedFile = true;
                                    se.VswFilename = sf1.FileName;
                                    break;
                            }
                        }
                        else
                        {
                            se = lpDt.updateSimulationEntity(se);
                            VswFile ds = new VswFile();
                            ds.saveVswfile(se, se.VswFilename);
                            se.SavedFile = true;
                        }
                        return;
                        break;
                    case DialogResult.No:
                        se.SavedFile = true;
                        return;
                        break;
                    case DialogResult.Cancel:
                        se.SavedFile = true;
                        break;
                }
                //return;
            }
        }
        private void rEPFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            se.RepFile = se.ResultFolderpath + "\\" + se.ProjectName + ".REP";
            CommandLineProcess cmd = new CommandLineProcess();
            cmd.Command = "notepad";
            cmd.Arguments = se.RepFile;
            bool bSuccess = cmd.Start();
            if (!bSuccess)
            {
                MessageBox.Show("Could not open Report file " + se.RepFile + " \nContact Support");
                return;
            }
        }

        private void singleREPFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CommandLineProcess cmd = new CommandLineProcess();
            cmd.Command = "notepad";
            cmd.Arguments = se.SingleRepFile;
            bool bSuccess = cmd.Start();
            if (!bSuccess)
            {
                MessageBox.Show("Could not open Single Simulation Report file " + se.RepFile + " \nContact Support");
                return;
            }
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            saveToolStripMenuItem_Click(sender, e);
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            exitToolStripMenuItem_Click(sender, e);
        }
        
        private void gridCalculatorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmMapCalculator fm1 = new frmMapCalculator(false,se);
            fm1.Show();
        }
        
        private void controlPointCalculatorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmControlPointsCalculator frmcpc1 = new frmControlPointsCalculator();
            frmcpc1.Show();
        }
        
        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (se.SavedFile)
            {
                return;
            }
            else
            {
                var mb_ret = MessageBox.Show(this,
                    "File not Saved, do you want to Save?",
                    "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                switch (mb_ret)
                {
                    case DialogResult.Yes:
                        if (se.NewFile)
                        {
                            SaveFileDialog sf1 = new SaveFileDialog();
                            sf1.Filter = "Velsto project files|*.vsw";
                            sf1.FilterIndex = 1;
                            var mb_ret2 = sf1.ShowDialog();
                            VswFile ds = new VswFile();
                            switch (mb_ret2)
                            {
                                case DialogResult.Cancel:
                                    break;
                                default:
                                    se = lpDt.updateSimulationEntity(se);
                                    ds.saveVswfile(se, sf1.FileName);
                                    se.SavedFile = true;
                                    se.VswFilename = sf1.FileName;
                                    break;
                            }
                        }
                        else
                        {
                            se = lpDt.updateSimulationEntity(se);
                            VswFile ds = new VswFile();
                            ds.saveVswfile(se, se.VswFilename);
                            se.SavedFile = true;
                        }
                        break;
                    case DialogResult.No:
                        se.SavedFile = true;
                        break;
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;
                }
            } 
        }

        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            AboutBox1 ab1 = new AboutBox1();
            ab1.Show();
        }

        private void onLineDocumentationToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
               System.Diagnostics.Process.Start("chrome.exe", "www.velsto.org/downloads/Velsto_User_Instructions_121.pdf");
            }
            catch (Exception ex)
            {
                try
                {
                    System.Diagnostics.Process.Start("iexplore.exe", "www.velsto.org/downloads/Velsto_User_Instructions_121.pdf");

                }
                catch (Exception ex2)
                {
                    MessageBox.Show("Need Chrome or Internet Explorer to view documentation this way \n" +
                                    "available as www.velsto.org/downloads/Velsto_User_Instructions_121.pdf or " +
                                    "in C:\\data\\Velsto\\docs");
                }
            }
        }

        #endregion


        
        private void projNameTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((e.Handled = (e.KeyChar == (char)Keys.Space) || (e.Handled = (e.KeyChar == '\\' ))))
            {
                MessageBox.Show("Spaces or Backslashes are not allowed");
            }
        } 

        private void projNameTextBox_Validated(object sender, EventArgs e)
        {
            
            se.ProjectName = projNameTextBox.Text;
            if (!fileOpening)
            {
                se.SavedFile = false;
            }
            
        }

        
        private void resultFolderButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fb1 = new FolderBrowserDialog();
            var mb_ret = fb1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    resultFolderTextBox.Text = fb1.SelectedPath;
                    se.ResultFolderpath = fb1.SelectedPath;
                    break;
            }
        }
        
        private void bu_gen_moreinfo_Click(object sender, EventArgs e)
        {
            if (lb_gen_moreinfo.Visible == false)
            {
                lb_gen_moreinfo.Visible = true;
                bu_gen_moreinfo.Text = "Hide Info";
            }
            else
            {
                lb_gen_moreinfo.Visible = false;
                bu_gen_moreinfo.Text = "Info";
            }
        }
 

        #region Datagridview

        private void setuplpDgv()
        {
            // setup Layer Params Data Grid View source from Layers Params Data Table
            lpDgv.DataSource = lpDt;

            alVtypes.Add(Constants.VEL_SELECT);
            alVtypes.Add(Constants.VEL_VINT);
            alVtypes.Add(Constants.VEL_VINT_GRID);
            alVtypes.Add(Constants.VEL_V0K);
            alVtypes.Add(Constants.VEL_V0_GRID_K);
            alVtypes.Add(Constants.VEL_LINREG);
            DataGridViewButtonColumn cbu1 = new DataGridViewButtonColumn();
            lpDgv.Columns.Insert(Constants.COL_TWTBUT, cbu1);
            DataGridViewButtonColumn cbu2 = new DataGridViewButtonColumn();
            lpDgv.Columns.Insert(Constants.COL_TWTDEVBUT, cbu2);
            DataGridViewComboBoxColumn cb1 = new DataGridViewComboBoxColumn();
            for (int i = 0; i < alVtypes.Count; i++)
            {
                cb1.Items.Add(alVtypes[i]);
            }
            lpDgv.Columns.Insert(Constants.COL_VSELCOMBO, cb1);



            DataGridViewDisableButtonColumn cbu3 = new DataGridViewDisableButtonColumn();
            lpDgv.Columns.Insert(Constants.COL_VBUT, cbu3);
            DataGridViewButtonColumn cbu4 = new DataGridViewButtonColumn();
            lpDgv.Columns.Insert(Constants.COL_VDEVBUT, cbu4);

            lpDgv.RowHeadersVisible = false;
            lpDgv.AllowUserToAddRows = false;
            lpDgv.Columns[Constants.COL_LAYERNR].Width = 30;
            lpDgv.Columns[Constants.COL_LAYERNR].ReadOnly = true;
            lpDgv.Columns[Constants.COL_LAYERNR].HeaderText = "";
            lpDgv.Columns[Constants.COL_TWTFILE].Width = 75;
            lpDgv.Columns[Constants.COL_TWTFILE].HeaderText = "Grid TWT(ms)";
            lpDgv.Columns[Constants.COL_TWTDEV].Width = 45;
            lpDgv.Columns[Constants.COL_TWTDEV].HeaderText = "\u03c3TWT (ms)";
            lpDgv.Columns[Constants.COL_TWTDEVFILE].Width = 75;
            lpDgv.Columns[Constants.COL_TWTDEVFILE].HeaderText = "Grid \u03c3TWT";
            lpDgv.Columns[Constants.COL_VSELCOMBO].Width = 110;
            lpDgv.Columns[Constants.COL_VSELCOMBO].HeaderText = "V Type";
            lpDgv.Columns[Constants.COL_K].Width = 45;
            lpDgv.Columns[Constants.COL_K].HeaderText = "K(1/s) G(m)";
            lpDgv.Columns[Constants.COL_V].Width = 60;
            lpDgv.Columns[Constants.COL_V].HeaderText = "V(m/s) F(m/s)";
            lpDgv.Columns[Constants.COL_VFILE].Width = 75;
            lpDgv.Columns[Constants.COL_VFILE].HeaderText = "Grid V";
            lpDgv.Columns[Constants.COL_VDEV].Width = 65;
            lpDgv.Columns[Constants.COL_VDEV].HeaderText = "\u03C3V(m/s) \u03C3F(m/s)";
            lpDgv.Columns[Constants.COL_VDEVFILE].Width = 75;
            lpDgv.Columns[Constants.COL_VDEVFILE].HeaderText = "Grid \u03c3V";
            lpDgv.Columns[Constants.COL_TWTBUT].Width = 100;
            lpDgv.Columns[Constants.COL_TWTBUT].HeaderText = "";
            lpDgv.Columns[Constants.COL_TWTBUT].ToolTipText = "Select grid (xyz file)"; 
            lpDgv.Columns[Constants.COL_TWTDEVBUT].Width = 110;
            lpDgv.Columns[Constants.COL_TWTDEVBUT].HeaderText = "";
            lpDgv.Columns[Constants.COL_VBUT].Width = 80;
            lpDgv.Columns[Constants.COL_VBUT].HeaderText = "";
            lpDgv.Columns[Constants.COL_VDEVBUT].Width = 90;
            lpDgv.Columns[Constants.COL_VDEVBUT].HeaderText = "";
            lpDgv.Columns[Constants.COL_DEPVEL].Width = 45;
            lpDgv.Columns[Constants.COL_DEPVEL].HeaderText = "DepVel    (%)";
            lpDgv.Columns[Constants.COL_DEPV0K].Width = 45;
            lpDgv.Columns[Constants.COL_DEPV0K].HeaderText = "DepV0k    (%)";
            lpDgv.Columns[Constants.COL_LAYERNAME].Width = 100;
            lpDgv.Columns[Constants.COL_LAYERNAME].HeaderText = "Layername";

            lpDgv.Columns[Constants.COL_DEPV0K].Visible = false;
            lpDgv.Columns[Constants.COL_DEPVEL].Visible = false;

            lpDgv.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
            for (int i = 0; i < lpDgv.Columns.Count; i++)
            {
                lpDgv.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            
        }

        private void lpDgv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            lpDgv.Rows[e.RowIndex].ErrorText = "";
            double newDouble;
            // Don't try to validate the 'new row' until finished 
            // editing since there
            // is not any point in validating its initial value.
            if (lpDgv.Rows[e.RowIndex].IsNewRow) { return; }
            // Validate Numeric columns(4-8)
            
            if (e.ColumnIndex==Constants.CELL_COL_TWTDEV &&
                (!double.TryParse(e.FormattedValue.ToString(),
                out newDouble) || newDouble < 0.0)
               )
            {
                e.Cancel = true;
                MessageBox.Show("Parameter " + e.ColumnIndex.ToString() + " must be numeric");
                lpDgv.Rows[e.RowIndex].ErrorText = "the value must be a number";
            }
            if ( e.ColumnIndex == Constants.CELL_COL_K &&
                (!double.TryParse(e.FormattedValue.ToString(),
                out newDouble))
               )
            {
                e.Cancel = true;
                MessageBox.Show("Parameter " + e.ColumnIndex.ToString() + " must be numeric");
                lpDgv.Rows[e.RowIndex].ErrorText = "the value must be a number";
            }
            int newInt;
            if (( e.ColumnIndex == Constants.CELL_COL_V
               || e.ColumnIndex == Constants.CELL_COL_VDEV
                ) &&
                (!int.TryParse(e.FormattedValue.ToString(),
                  out newInt) || newInt < 0)
               )
            {
                e.Cancel = true;
                MessageBox.Show("Parameter " + e.ColumnIndex.ToString() + " must be integer");
                lpDgv.Rows[e.RowIndex].ErrorText = "the value must be a integer";
            }
            if (( e.ColumnIndex == Constants.CELL_COL_DEPV0K
               || e.ColumnIndex == Constants.CELL_COL_DEPVEL) &&
               (!int.TryParse(e.FormattedValue.ToString(),
                 out newInt))
               )
            {
                e.Cancel = true;
                MessageBox.Show("Parameter " + e.ColumnIndex.ToString() + " must be integer");
                lpDgv.Rows[e.RowIndex].ErrorText = "the value must be a integer";
            }
            // Check if Velocity type has been selected
            if (e.ColumnIndex == Constants.CELL_COL_VSELCOMBO)
            {
                if (e.FormattedValue.ToString() == Constants.VEL_SELECT)
                {
                    e.Cancel = true;
                    MessageBox.Show("Please Select Velocity type");                   
                }
                // Save selectedindex from ComboBox Velocity type
                else
                {
                    for (int i = 0; i < alVtypes.Count; i++)
                    {
                        if (alVtypes[i].Equals(e.FormattedValue.ToString()))
                        {
                            ((LayerparamsEntity)se.AlLayerParams[e.RowIndex]).V0vintOption
                            = i;
                        }
                        
                    }
                }
            }
            // force rejoin when Grid select buttons clicked
            if (e.ColumnIndex == Constants.CELL_COL_TWTFILE
                || e.ColumnIndex == Constants.CELL_COL_TWTDEVFILE
                || e.ColumnIndex == Constants.CELL_COL_VFILE
                || e.ColumnIndex == Constants.CELL_COL_VDEVFILE)
            {
                se.GridsJoined = false;
                /*if (!e.FormattedValue.ToString().Equals("") && !File.Exists(e.FormattedValue.ToString()))
                {
                    e.Cancel = true;
                    MessageBox.Show("Grid file not existing use Get Grid button");
                }*/
            }
        }

        private void lpDgv_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (!fileOpening)
            {
                se.SavedFile = false;
            }
            //MessageBox.Show("Gridview validated");
            se = lpDt.updateSimulationEntity(se); 
            if (e.ColumnIndex == Constants.CELL_COL_LAYERNAME)
            {
                setLayerComboboxes();
            }
        }

        private void lpDgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > -1)
            {
                // Enable/Disable Buttons and TextBoxes according to Velocity option
                if (e.ColumnIndex == Constants.CELL_COL_VSELCOMBO)
                {
                    DataGridViewComboBoxCell comboCell =
                                                        (DataGridViewComboBoxCell)lpDgv.
                                                        Rows[e.RowIndex].Cells[Constants.CELL_COL_VSELCOMBO];
                    for (int i = 0; i < alVtypes.Count; i++)
                    {
                        if (alVtypes[i].Equals(comboCell.Value.ToString()))
                        {
                            ((LayerparamsEntity)se.AlLayerParams[e.RowIndex]).V0vintOption
                            = i;
                        }

                    }
                    if (Constants.VEL_VINT.Equals(comboCell.Value.ToString()))
                    {
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).Value = "";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).ReadOnly = true;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).Value = "0";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).ReadOnly = true;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).ReadOnly = false;
                        ((DataGridViewDisableButtonCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VBUT]).Enabled = false;
                        lpDgv.Invalidate();
                    }
                    else if (Constants.VEL_VINT_GRID.Equals(comboCell.Value.ToString()))
                    {
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).ReadOnly = false;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).Value = "0";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).ReadOnly = true;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).Value = "0";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).ReadOnly = true;
                        ((DataGridViewDisableButtonCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VBUT]).Enabled = true;
                        lpDgv.Invalidate();
                    }
                    else if (Constants.VEL_V0K.Equals(comboCell.Value.ToString()) ||
                             Constants.VEL_LINREG.Equals(comboCell.Value.ToString()))
                    {
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).Value = "";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).ReadOnly = true;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).ReadOnly = false;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).ReadOnly = false;
                        ((DataGridViewDisableButtonCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VBUT]).Enabled = false;
                        lpDgv.Invalidate();
                    }
                    else if (Constants.VEL_V0_GRID_K.Equals(comboCell.Value.ToString()))
                    {
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VFILE]).ReadOnly = false;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_K]).ReadOnly = false;
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).Value = "0";
                        ((DataGridViewTextBoxCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_V]).ReadOnly = true;
                        ((DataGridViewDisableButtonCell)lpDgv.Rows[e.RowIndex].Cells[Constants.CELL_COL_VBUT]).Enabled = true;
                        lpDgv.Invalidate();
                    }
                }
            }
        }

        private void lpDgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (lpDgv.IsCurrentCellDirty &&
                lpDgv.CurrentCell.ColumnIndex == Constants.CELL_COL_VSELCOMBO)
            {
                lpDgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        private void lpDgv_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex == Constants.CELL_COL_TWTFILE
             || e.ColumnIndex == Constants.CELL_COL_TWTDEVFILE
             || e.ColumnIndex == Constants.CELL_COL_VFILE
             || e.ColumnIndex == Constants.CELL_COL_VDEVFILE)
            {
                CommandLineProcess cmd = new CommandLineProcess();
                cmd.Command = "notepad.exe";
                cmd.Arguments = (string)lpDgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                bool bSuccess = cmd.Start();
                if (!bSuccess)
                {
                    MessageBox.Show("Could not open file " + lpDgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value + " \nContact Support");
                    return;
                }
            }
        }
        

        private void addLayerAboveButton_Click(object sender, EventArgs e)
        {
            if (lpDt.Rows.Count == 10)
            {
                MessageBox.Show("Nr.Layers can't be > 10");
            }
            else
            {
                // Insert Layer in Datatable above selected 
                // and paint Buttons in generated Row in DataGridView
                int i = lpDgv.SelectedCells[0].RowIndex;
                lpDt.insertRow(i);
                lpDgv.Rows[i].Height = 20;
                ((DataGridViewComboBoxCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VSELCOMBO])).Value =
                 alVtypes[0];
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).Value = Constants.TWTBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).Value = Constants.VBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).Value = Constants.VDEVBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).Value = Constants.TWTDEVBUTTONTEXT;
                se.NrLayers++;
                nrLayersTextBox.Text = Convert.ToString(se.NrLayers);

                
                se.SavedFile = false;
                se = lpDt.updateSimulationEntity(se);
                setLayerComboboxes();
                // Update v0vintoption in Simulationentity
                for (int j = 0; j < lpDgv.RowCount; j++)
                {
                    for (int i2 = 0; i2 < alVtypes.Count; i2++)
                    {
                        if (alVtypes[i2].Equals(lpDgv.Rows[j].Cells[Constants.CELL_COL_VSELCOMBO].FormattedValue))
                        {
                            ((LayerparamsEntity)se.AlLayerParams[j]).V0vintOption
                            = i2;
                        }
                    }
                }
            }
        }

        private void addLayerBelowButton_Click(object sender, EventArgs e)
        {
            if (lpDt.Rows.Count == 10)
            {
                MessageBox.Show("Nr.Layers can't be > 10");
            }
            else
            {
                // Insert Layer in Datatable below selected 
                // and paint Buttons in generated Row in DataGridVie
                int i = lpDgv.SelectedCells[0].RowIndex + 1;
                lpDt.insertRow(i);
                lpDgv.Rows[i].Height = 20;
                ((DataGridViewComboBoxCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VSELCOMBO])).Value =
                 alVtypes[0];
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).Value = Constants.TWTBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).Value = Constants.VBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).Value = Constants.VDEVBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).Value = Constants.TWTDEVBUTTONTEXT;
                se.NrLayers++;
                nrLayersTextBox.Text = Convert.ToString(se.NrLayers);

                
                se.SavedFile = false;
                se = lpDt.updateSimulationEntity(se);
                setLayerComboboxes();
                // Update v0vintoption in Simulationentity
                for (int j = 0; j < lpDgv.RowCount; j++)
                {
                    for (int i2 = 0; i2 < alVtypes.Count; i2++)
                    {
                        if (alVtypes[i2].Equals(lpDgv.Rows[j].Cells[Constants.CELL_COL_VSELCOMBO].FormattedValue))
                        {
                            ((LayerparamsEntity)se.AlLayerParams[j]).V0vintOption
                            = i2;
                        }
                    }
                }
            }
        }

        private void deleteLayerButton_Click(object sender, EventArgs e)
        {
            if (lpDt.Rows.Count == 2)
            {
                MessageBox.Show("Nr.Layers can't be < 2");
            }
            else
            {
                lpDt.Rows.RemoveAt(lpDgv.SelectedCells[0].RowIndex);
                se.NrLayers--;
                nrLayersTextBox.Text = Convert.ToString(se.NrLayers);

                setLayerComboboxes();
                
                se.SavedFile = false;
                se = lpDt.updateSimulationEntity(se);
                for (int i = 0; i < lpDt.Rows.Count; i++)
                {
                    lpDt.Rows[i][0] = i + 1;
                }
                // Update v0vintoption in Simulationentity
                for (int j = 0; j < lpDgv.RowCount; j++)
                {
                    for (int i2 = 0; i2 < alVtypes.Count; i2++)
                    {
                        if (alVtypes[i2].Equals(lpDgv.Rows[j].Cells[Constants.CELL_COL_VSELCOMBO].FormattedValue))
                        {
                            ((LayerparamsEntity)se.AlLayerParams[j]).V0vintOption
                            = i2;
                        }
                    }
                }
            }
        }

        

        private void lpDgv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
/*
 * Method for handling FileOpen dialog 4 types of Grid files in DataGridView
 * TWT file Buttons, TWTdev file Buttons, VVN file Button and VVNdev file Button
 * Results fill in in LayeresParameterDataTable
 */
            if (e.ColumnIndex == Constants.CELL_COL_TWTBUT || 
                e.ColumnIndex == Constants.CELL_COL_TWTDEVBUT || 
                e.ColumnIndex == Constants.CELL_COL_VBUT ||
                e.ColumnIndex == Constants.CELL_COL_VDEVBUT)
            {
                OpenFileDialog of1 = new OpenFileDialog();
                int fileCol = 0;
                switch (e.ColumnIndex)
                {
                    case Constants.CELL_COL_TWTBUT:
                        of1.Filter = "Grid TWT files|*.twt|All files|*.*";
                        fileCol = Constants.LPDT_COL_TWTFILE;
                        break;
                    case Constants.CELL_COL_TWTDEVBUT:
                        of1.Filter = "Grid TWTdev files|*.twtdev|All files|*.*";
                        fileCol = Constants.LPDT_COL_TWTDEVFILE;
                        break;
                    case Constants.CELL_COL_VBUT:
                        of1.Filter = "Grid VVN files|*.vvn|All files|*.*";
                        fileCol = Constants.LPDT_COL_VFILE;
                        break;
                    case Constants.CELL_COL_VDEVBUT:
                        of1.Filter = "Grid VVNdev files|*.vvndev|All files|*.*";
                        fileCol = Constants.LPDT_COL_VDEVFILE;
                        break;
                    default:
                        break;
                }
                var mb_ret = of1.ShowDialog();
                switch (mb_ret)
                {
                    case DialogResult.Cancel:
                        break;
                    default:
                        lpDt.Rows [e.RowIndex][fileCol] = of1.FileName;
                        se.SavedFile = false;
                        se.GridsJoined = false;
                        se = lpDt.updateSimulationEntity(se);
                        lpDgv.Refresh();
                        break;
                }
            }

        }

        private void tabPage2_Paint(object sender, PaintEventArgs e)
        {
            // force repaint of Button cell texts
            for (int i = 0; i < lpDgv.Rows.Count; i++)
            {
                ((DataGridViewComboBoxCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VSELCOMBO])).Value =
                            alVtypes[((LayerparamsEntity)se.AlLayerParams[i]).V0vintOption];
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).Value = Constants.TWTBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).Value = Constants.VBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).Value = Constants.VDEVBUTTONTEXT;
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).Value = Constants.TWTDEVBUTTONTEXT;
            }
            for (int i = 0; i < lpDgv.Rows.Count; i++)
            {
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTBUT])).ToolTipText = "Get grid (xyz file)";
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_TWTDEVBUT])).ToolTipText = "Get grid (xyz file)";
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VBUT])).ToolTipText = "Get grid (xyz file)";
                ((DataGridViewButtonCell)(lpDgv.Rows[i].Cells[Constants.CELL_COL_VDEVBUT])).ToolTipText = "Get grid (xyz file)";
            }
        }

        #endregion

        #region Run Simulation


        private void simulOptionBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.SimulOption = simulOptionBox.SelectedIndex + 1;
            //MessageBox.Show("Simul1 " + se.SimulOption.ToString());
        }


        private void simulnr_textBox_Validating(object sender, CancelEventArgs e)
        {
            int newInt;
            if (!int.TryParse(simulnr_textBox.Text,
                out newInt) || newInt < 2 || newInt > 2000)
            {
                e.Cancel = true;
                MessageBox.Show("Number of Realisations must be between 2 and 2000");
            }
            else
            {
                se.SimulNr = newInt;
            }
        }
        
        // On worker thread so do our thing!
        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Threading.Thread.Sleep(1000);
            
            FileInfo fi = new FileInfo(se.SdzFile);
            double sdzlength = 20.0 + (se.NrLayers * 8.0) + 1.0;
            long lold = 0;
            // Your background task goes here
            for (int i = 0; i <= 3600; i++)
            {
                fi.Refresh();
                //MessageBox.Show(fi.Length.ToString());
                int i2 = Convert.ToInt32( (((double) fi.Length) / (((double)se.NrPoints)*sdzlength))*100.0);
                i2 = Math.Min(100, i2);
                // Report progress to 'UI' thread
                backgroundWorker1.ReportProgress(i2);
                // Simulate long task
                System.Threading.Thread.Sleep(1000);
                if (fi.Length == lold)
                {
                    cbgen2.Close();
                    MessageBox.Show("Simulation completed\nCheck Output->Rep");
                    break;
                }
                else
                {
                    lold = fi.Length;
                }
            }
            cbgen2.Close();
        }
        // Back on the 'UI' thread so we can update the progress bar
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // The progress percentage is a property of e
            cbgen2.Progress(" ",e.ProgressPercentage,"Simulation exp.duration " + timesim.ToString("0.0") + "(min)(on 3Ghz machine)");
        }
        // method to run simulations various checks beforehand
        private void runButton_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(se.ResultFolderpath))
            {
                MessageBox.Show("Resultfolder not existing check in General tab");
                return;
            }
            if (!se.GridsJoined)
            {
                MessageBox.Show("First Prepare Simulation Grid");
                return;
            }
            Directory.SetCurrentDirectory(se.TempFolderpath);
            

            string velsimexe = Application.StartupPath + "\\Velsim.exe";
            string inpfile = se.TempFolderpath + "\\" + se.ProjectName + ".INP";
            string inpsinglefile = se.TempFolderpath + "\\" + se.ProjectName + "_SINGLE.INP";
            string runvelsimfile = se.TempFolderpath + "\\" + se.ProjectName + "_RUN.BAT";
            se.RunVelsimFile = runvelsimfile;
            string runvelsimsinglefile = se.TempFolderpath + "\\" + se.ProjectName + "_RUN_SINGLE.BAT";
            // Batch simulationrun
            if (se.SimulOption == Constants.SIM_FULL_TD
             || se.SimulOption == Constants.SIM_FULL)
            {
                // create INP file (Parameters for simulation)
                InpFile inpf = new InpFile();
                se.ErrorMessage = inpf.saveInpfile_Velsim(ref se, inpfile);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(this, se.ErrorMessage, "**Error**",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                // Create Simulation batch file
                RunVelsimFile rdf = new RunVelsimFile();
                se.ErrorMessage = rdf.saveRunVelsimFile(se, velsimexe, inpfile, runvelsimfile);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(this, se.ErrorMessage, "**Error**",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                Thread t = new Thread(new ThreadStart(batch_Runvelsim));
                t.IsBackground = true;
                t.Start();
                if (se.SimulOption == Constants.SIM_FULL || se.SimulOption == Constants.SIM_FULL_TD)
                {   
                    if (se.SimulOption == Constants.SIM_FULL)
                    {
                        timesim = (se.NrPoints / 41000.0) * (se.NrLayers / 5.0) * 1.5 * ((double)se.SimulNr/2000.0);
                    }
                    else if (se.SimulOption == Constants.SIM_FULL_TD)
                    {
                        timesim = (se.NrPoints / 41000.0) * (se.NrLayers / 5.0) * 1.5 * (1.0/2000.0);
                    }
                    if (timesim < 60.0)
                    {
                        backgroundWorker1.RunWorkerAsync();
                        cbgen2 = new cBack();
                        cbgen2.Show();
                    }
                    else
                    {
                        MessageBox.Show("The Simulation has been submitted in Batch\r\n"
                        + "nr of Points : " + se.NrPoints.ToString() + "\r\n"
                        + "estimated duration (on 3 Ghz machine) : " + timesim.ToString("0.0") + " (min)\r\n"
                        + "For completion check if the Command process(black window) disappeared\r\n"
                        + "You may exit Velsto but do not switch of your PC");
                    }
                }
                return;
            }

            // Direct Simulation (Single point)
            else if (se.SimulOption == Constants.SIM_SINGLE_POINT_TD
                   || se.SimulOption == Constants.SIM_SINGLE_POINT)
            {
                if (!se.SingleSelected)
                {
                    MessageBox.Show("First Select single point");
                    return;
                }
                // create INP file (Parameters for simulation)
                InpFile inpf = new InpFile();
                se.ErrorMessage = inpf.saveInpfile_Velsim(ref se, inpsinglefile);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(this, se.ErrorMessage, "**Error**",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                // Create Simulation batch file
                RunVelsimFile rdf = new RunVelsimFile();
                se.ErrorMessage = rdf.saveRunVelsimFile(se, velsimexe, inpsinglefile, runvelsimsinglefile);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(this, se.ErrorMessage, "**Error**",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                // Use class downloaded from Google to run Dust
                /*CommandLineProcess cmd = new CommandLineProcess();*/
                cmd.Command = runvelsimsinglefile;
                // catch run exited event
                cmd.Exited += new CommandLineProcess.ExitedEventHandler(cmd_Exited);
                bool bSuccess = cmd.Start();
                if (!bSuccess)
                {
                    MessageBox.Show("Could not start Velsim\nContact Support");
                    cmd.Exited -= new CommandLineProcess.ExitedEventHandler(cmd_Exited);
                    return;
                }
                return;
            }
            else
            {
                MessageBox.Show("Invalid Simulation option");
                return;
            }
        }

        // Method to catch Dust exited event (and Show results).
        // se.CommanDone bool variable used to prevent multiple popups(bug)
        private void cmd_Exited(object sender, EventArgs e)
        {
            cmd.Exited -= new CommandLineProcess.ExitedEventHandler(cmd_Exited);
            if (cmd.ExitCode == 0)
            {
                cmd.Close() ;
                // the following is necessary for thread safe invoking
                // of the Single Results Form (from FormMain)
                // call_sireCallBack is a delegate
                if (this.InvokeRequired)
                {
                    call_sireCallback d = new call_sireCallback(call_sire);
                    this.Invoke(d);
                }
                else
                {
                    /*MessageBox.Show("No Invoke");*/
                    call_sire();
                }
            }
            else
            {
                MessageBox.Show("Single point run failed\r\nyour input maybe in error\r\ncheck Output->Single Rep");
                cmd.Close();
            }
            return;
        }

        // method to call Single Results Form
        private void call_sire()
        {
                FormSingleresults fsr = new FormSingleresults(se,alVtypes);
                fsr.Show();
        }

        private void batch_Runvelsim()
        {
            System.Diagnostics.Process.Start(se.RunVelsimFile);
        }

        #endregion

        

        

        #region Join grids

        private void joinGridsButton_Click(object sender, EventArgs e)
        {
            se.GridsCondOption = Constants.GRID_EQ;
            joinGrids();
        }
        
        private void joinGrids()
        {
            if (se.ResultFolderpath.Length == 0)
            {
                MessageBox.Show("First specify Result Folder in General tab");
                return;
            }
            //Application.UseWaitCursor = true;
            Cursor.Current = Cursors.WaitCursor;
            this.addLayerAboveButton.Enabled = false;
            this.addLayerBelowButton.Enabled = false;
            this.deleteLayerButton.Enabled = false;
            this.runButton.Enabled = false;
            this.saveButton.Enabled = false;
            this.exitButton.Enabled = false;
            this.joinUnequalButton.Enabled = false;
            this.resultFolderButton.Enabled = false;
            this.toolStripMenuItem1.Enabled = false;
            this.outputToolStripMenuItem.Enabled = false;
            this.pointSelButton.Enabled = false;
            this.showMapButton.Enabled = false;
            lpDgv.Enabled = false;
            // get nr of Grids for Progressbar
            int i2 = 0;
            string tempFile = "";
            try
            {
                if (!((string)se.InputFileTWT).Equals("")) { i2++; }
            }
            catch (InvalidCastException ex)
            {
                se.InputFileTWT = "";
            }
            if (!((string)se.InputFileTWT).Equals("")) { i2++; }
            for (int i=0; i<se.NrLayers; i++)
            {
                try
                {
                    if (((string)se.InputFileTWT).Equals("")
                        && !((string)se.AlInputFileTWT[i]).Equals("")) { i2++; }
                }
                catch (InvalidCastException ex)
                {
                    se.AlInputFileTWT[i] = "";
                }
                try
                {
                    if (!((string)se.AlInputFileTWTdev[i]).Equals("")) { i2++; }
                }
                catch (InvalidCastException ex)
                {
                    se.AlInputFileTWTdev[i] = "";
                }
                try
                {
                    if (!((string)se.AlInputFileV0[i]).Equals("")) { i2++; }
                }
                catch (InvalidCastException ex)
                {
                    se.AlInputFileV0[i] = "";
                }
                try
                {
                    if (!((string)se.AlInputFileVVNdev[i]).Equals("")) { i2++; }
                }
                catch (InvalidCastException ex)
                {
                    se.AlInputFileVVNdev[i] = "";
                }

            }
            pBar1.Enabled = true;
            pBar1.Minimum = 0;
            pBar1.Maximum = i2;
            pBar1.Value = 0;
            pBar1.Visible = true;
            //pBar1.Show();

            se.NrJoinedGrids = 1;
            se.ErrorMessage = null;

            XYPointFile xypFile = new XYPointFile();
            // Create Joined TWT Grid
            //se = xypFile.writeJoinedTWTFile(se);
            se = writeJoinedTWTFile(se);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                enableButtons();
                return;
            }
            //pBar1.Value = se.NrJoinedGrids;
            
            // Add TWT Dev Grids
            // If Grids in s set conversion factor
            double stomsfactor = 1.0;
            //if (se.GridTWTdevinseconds)
            //{
            //    stomsfactor = 1000.0;
            //}
            //se = xypFile.writeJoinedArraylistFile(se, se.AlInputFileTWTdev, 10, stomsfactor);
            se = writeJoinedArraylistFile(se, se.AlInputFileTWTdev, 10);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                se.ErrorMessage = "";
                pBar1.Visible = false;
                enableButtons();
                return;
            }
            //pBar1.Value = se.NrJoinedGrids;

            // Add V Grids
            se = writeJoinedArraylistFile(se, se.AlInputFileV0, 20);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                se.ErrorMessage = "";
                pBar1.Visible = false;
                enableButtons();
                return;
            }
            //pBar1.Value = se.NrJoinedGrids;

            // Add VDev Grids
            se = writeJoinedArraylistFile(se, se.AlInputFileVVNdev,30);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                se.ErrorMessage = "";
                pBar1.Visible = false;
                enableButtons();
                return;
            }
            //pBar1.Value = se.NrJoinedGrids;
            // MessageBox.Show("Grids joined succesfully\r\nReady for simulations");
            se.GridsJoined = true;
            pBar1.Visible = false;
            //Application.UseWaitCursor = false;
            Cursor.Current = Cursors.Default;
            enableButtons();            
            return;
        }

        // Method to Enable buttons etc. when Join Finished/Aborted
        private void enableButtons()
        {
            Cursor.Current = Cursors.Default;
            this.addLayerAboveButton.Enabled = true;
            this.addLayerBelowButton.Enabled = true;
            this.deleteLayerButton.Enabled = true;
            this.runButton.Enabled = true;
            this.saveButton.Enabled = true;
            this.exitButton.Enabled = true;
            this.joinUnequalButton.Enabled = true;
            this.resultFolderButton.Enabled = true;
            this.wellLayerFileButton.Enabled = true;
            this.toolStripMenuItem1.Enabled = true;
            this.outputToolStripMenuItem.Enabled = true;
            this.pointSelButton.Enabled = true;
            this.showMapButton.Enabled = true;
            se.SingleSelected = false;
            xTextBox.Text = "";
            yTextBox.Text = "";
            lpDgv.Enabled = true;
        }
        private void joinUnequalButton_Click(object sender, EventArgs e)
        {
            se.GridsCondOption = Constants.GRID_UNEQCOMREF;
            joinGrids();
        }

        // Method to create joined file from specified TWT XYgrids, if Joined TWT
        // file specified take that one 
        public SimulationEntity writeJoinedTWTFile(SimulationEntity se)
        {
            string inputFile, outputFile, layerFile;

            // if Joined TWT Inputfile available no joining TWT file
            if (!se.InputFileTWT.Equals(""))
            {
                inputFile = se.InputFileTWT;
                //se.ErrorMessage = se.InputFileTWT;
                //return se;
                if (!File.Exists(inputFile))
                {
                    se.ErrorMessage = "Cannot find Joined TWT file " + se.InputFileTWT;
                    return se;
                }
                else
                {
                    char[] delimiterChars = { ' ', '\t' };
                    File.OpenRead(inputFile);

                    // Check if ne Layers in Joined file = nr Layers in Model
                    TextReader readJoinTWT = new StreamReader(inputFile);
                    string line = "";
                    line = readJoinTWT.ReadLine();
                    string[] words = line.Split(delimiterChars,
                                                StringSplitOptions.RemoveEmptyEntries);
                    if (words.Length != (2 + se.NrLayers))
                    {
                        se.ErrorMessage = "Nr Layers in Joined TWT file " +
                                          (words.Length - 2).ToString() +
                                          "\r\ndoes not match Nr Layers Model " +
                                          se.NrLayers.ToString();
                        return se;
                    }

                }
                se.JoinInputFile = inputFile;
            }
            else
            // join Single layer TWT files
            {
                try
                {
                    inputFile = (string)se.AlInputFileTWT[0];
                }
                catch (InvalidCastException ex)
                {
                    se.ErrorMessage = "No/Invalid TWT file layer 1";
                    return se;
                }

                if (!File.Exists(inputFile))
                {
                    se.ErrorMessage = "Invalid TWT file layer 1 " + inputFile;
                    return se;
                }
                for (int i = 1; i < se.NrLayers; i++)
                {
                    try
                    {
                        layerFile = (string)se.AlInputFileTWT[i];
                    }
                    catch (InvalidCastException ex)
                    {
                        se.ErrorMessage = "No/Invalid TWT file layer" + (i + 1).ToString();
                        return se;
                    }
                    if (!File.Exists(layerFile))
                    {
                        se.ErrorMessage = "No/Invalid TWT file layer" + (i + 1).ToString() + layerFile;
                        return se;
                    }
                    outputFile = se.TempFolderpath + "\\" + se.ProjectName + "_join" + (i + 1).ToString() + ".join";
                    /*se.ErrorMessage = outputFile;*/
                    string sret;
                    // select Joining method
                    if (se.GridsCondOption == Constants.GRID_UNEQCOMREF)
                    {
                        sret = joinLayer(inputFile, layerFile, outputFile);
                        if (sret != null)
                        {
                            se.ErrorMessage = sret;
                            return se;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Invalid Grid Conditioning option");
                        return se;
                    }
                    inputFile = outputFile;
                    se.NrJoinedGrids++;
                    se.JoinInputFile = outputFile;
                }
            }
            return se;
        }

        // Method to create joined file from inputfile and XYGrids in ArrayList al
        // fileseq = number for unique filenaming
        // stomsfactor is factor if Grid TWTdev is in s(1000.0) otherwise 1.0
        public SimulationEntity writeJoinedArraylistFile(SimulationEntity se,
            ArrayList al, int fileseq)
        {
            string inputFile, outputFile, layerFile;
            // check if Inputfile exists
            inputFile = (string)se.JoinInputFile;

            if (!File.Exists(inputFile))
            {
                se.ErrorMessage = "Input Join file " + inputFile + " not existing";
                return se;
            }

            // For all XYGrids in al Join
            for (int i = 0; i < se.NrLayers; i++)
            {
                try
                {
                    layerFile = (string)al[i];
                }
                catch (InvalidCastException ex)
                {
                    layerFile = "";
                }
                outputFile = se.TempFolderpath + "\\" + se.ProjectName + "_join" + (fileseq + i + 1).ToString() + ".join";
                string sret;
                if (!layerFile.Equals(""))
                {
                    if (!File.Exists(layerFile))
                    {
                        se.ErrorMessage = "Grid file " + layerFile + " not existing";
                        return se;
                    }
                    if (se.GridsCondOption == Constants.GRID_UNEQCOMREF)
                    {
                        // Join XYGrid
                        sret = joinLayer(inputFile, layerFile, outputFile);
                        if (sret != null)
                        {
                            se.ErrorMessage = sret;
                            return se;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Invalid Grid Conditioning option");
                        return se;
                    }
                    inputFile = outputFile;
                    se.NrJoinedGrids++;
                    se.JoinInputFile = outputFile;
                }
            }
            return se;
        }


        // Method to join one grid file to input file
        
        public string joinLayer(string inputFile,
                                 string layerFile,
                                 string outputFile)
        {
            try
            {
                // First read Layerfile in memory(Dictionary)
                //MessageBox.Show(inputFile + "\r\n" + layerFile);
                int nrPoint = 0;
                string line = null;
                TextReader readGrid = new StreamReader(layerFile);
                Dictionary<Point, double> sl1 = new Dictionary<Point, double>();
                char[] delimiterChars = { ' ', '\t' };
                double v = 0.0;
                while ((line = readGrid.ReadLine()) != null)
                {
                    line = line.Replace(",", ".");
                    Point xy1 = new Point();
                    string[] words = line.Split(delimiterChars,
                                                StringSplitOptions.RemoveEmptyEntries);
                    xy1.X = (int)(Math.Round(parseDoubleString(words[0]),1) * 10.0);
                    if (xy1.X == -999990) return ("Non numeric characters in file");
                    xy1.Y = (int)(Math.Round(parseDoubleString(words[1]),1) * 10.0);
                    if (xy1.Y == -999990) return ("Non numeric characters in file");
                    if (!words[2].Contains("NaN"))
                    {
                        v = parseDoubleString(words[2]);
                        try
                        {
                            sl1.Add(xy1, v);
                        }
                        catch (ArgumentException e)
                        {
                            //MessageBox.Show(layerFile + " " + xy1.X.ToString() + " " + xy1.Y.ToString());
                        }
                    }
                }

                // Read inputfile, Join and Write outputfile
                TextReader readInputFile = new StreamReader(inputFile);
                TextWriter writeOutputFile = new StreamWriter(outputFile);
                while ((line = readInputFile.ReadLine()) != null)
                {
                    Point xy2 = new Point();
                    line = line.Replace(",", ".");
                    if (!line.Contains("NaN"))
                    {
                        string[] words2 = line.Split(delimiterChars,
                                                    StringSplitOptions.RemoveEmptyEntries);
                        xy2.X = (int)(Math.Round(parseDoubleString(words2[0]),1) * 10.0);
                        if (xy2.X == -9999) return ("Non numeric characters in file");
                        xy2.Y = (int)(Math.Round(parseDoubleString(words2[1]),1) * 10.0);
                        if (xy2.Y == -9999) return ("Non numeric characters in file");
                        try
                        {
                            v = sl1[xy2];
                            writeOutputFile.WriteLine(line + " " +
                            v.ToString("0.0000", CultureInfo.InvariantCulture));
                            nrPoint++;
                        }
                        catch (KeyNotFoundException ex)
                        {
                            v = -999.25;
                        }
                    }
                }
                se.NrPoints = nrPoint;
                writeOutputFile.Close();
                readInputFile.Close();
                sl1.Clear();
                return null;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }

        

        #endregion

        #region Single point selection
        // method to find Nearest point out of Joined Grid file
        private void pointSelButton_Click(object sender, EventArgs e)
        {
            XYPointFile spf = new XYPointFile();
            if (!se.GridsJoined)
            {
                MessageBox.Show("First Prepare Simulation Grid");
                return;
            }
            Cursor.Current = Cursors.WaitCursor;
            se = spf.writeSingleJoinedFile(se);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            }
            xTextBox.Text = (se.SingleFound.X/10.0).ToString();
            yTextBox.Text = (se.SingleFound.Y/10.0).ToString();
            se.SingleSelected = true;
            Cursor.Current = Cursors.Default;
            return;
        }

        private void xSelTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(xSelTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("X must be Numeric");
            }
        }

        private void xSelTextBox_Validated(object sender, EventArgs e)
        {
            if (xSelTextBox.Text != "")
            {
                xSelTextBox.Text = xSelTextBox.Text.Replace(",", ".");
                se.SingleSearch.X = (int) (parseDoubleString(xSelTextBox.Text) * 10.0);
            }
            else
            {
                se.SingleSearch.X = 0;
            }
        }
       
        private void ySelTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(ySelTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("Y must be Numeric");
            }
        }

        private void ySelTextBox_Validated(object sender, EventArgs e)
        {
            if (ySelTextBox.Text != "")
            {
                ySelTextBox.Text = ySelTextBox.Text.Replace(",", ".");
                se.SingleSearch.Y = (int)(parseDoubleString(ySelTextBox.Text) * 10.0);
            }
            else
            {
                se.SingleSearch.Y = 0;
            }
        }

        #endregion      

        #region Show map incl. Kriging


        private void maplayCb_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.MapSimLayernr = maplayCb.SelectedIndex + 1;
        }

        private void mapTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.MapType = mapTypeComboBox.SelectedIndex + 1;
        }

        private void showMapButton_Click(object sender, EventArgs e)
        {
            int mapType, layerNr;
            layerNr = se.MapSimLayernr;
            mapType = mapTypeComboBox.SelectedIndex + 1;
            resWorkflow = false;
            showMap(mapType, layerNr);
        }

        private void bu_gridinfo_Click(object sender, EventArgs e)
        {
            int mapType, layerNr;
            layerNr = se.MapSimLayernr;
            mapType = mapTypeComboBox.SelectedIndex + 1; se.MapType = mapType;
            se.MapLayernr = layerNr;
            if (se.MapType < 1)
            {
                MessageBox.Show("Define Gridtype first");
                return;
            }
            if (se.MapLayernr < 1 || se.MapLayernr > se.NrLayers)
            {
                MessageBox.Show("Layernr for Grid invalid");
                return;
            }
            switch (se.MapType)
            {
                case Constants.MAP_TWT:

                    gridFile = (string)se.AlInputFileTWT[se.MapLayernr - 1];
                    gridType = "TWT";
                    break;
                case Constants.MAP_TWTDEV:
                    gridFile = (string)se.AlInputFileTWTdev[se.MapLayernr - 1];
                    gridType = "TWTDEV";
                    break;
                case Constants.MAP_V:
                    gridFile = (string)se.AlInputFileV0[se.MapLayernr - 1];
                    gridType = "V";
                    break;
                case Constants.MAP_VDEV:
                    gridFile = (string)se.AlInputFileVVNdev[se.MapLayernr - 1];
                    gridType = "VDEV";
                    break;
                case Constants.MAP_Z:
                    gridFile = se.AvzFile;
                    gridType = "Z";
                    break;
                case Constants.MAP_ZDEV:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV";
                    break;
                case Constants.MAP_ZDEV_WELL:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV_WELL";
                    break;
                case Constants.MAP_WELL_BULL:
                    gridFile = se.SdzFile;
                    gridType = "WELL_BULL";
                    break;
                case Constants.MAP_ZDEV_WELL2:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV_WELL2";
                    break;
                case Constants.MAP_RES_KRIG:
                    gridFile = se.AvzFile;
                    gridType = "RES_KRIG";
                    break;
                case Constants.MAP_Z_WELL:
                    gridFile = se.AvzFile;
                    gridType = "Z_WEll";
                    break;
            }
            se.MapXyzFile = gridFile;
            if (!File.Exists(gridFile))
            {
                MessageBox.Show("Grid File " + gridFile + " does not exist");
                return;
            }
            XYPointFile xyf = new XYPointFile();
            se = xyf.getMapParams(se, gridFile);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            }
            MessageBox.Show("Info Grid File : " + gridFile + "\n" +
                            "XMin : " + se.GridXMin + "\n" +
                            "XMax : " + se.GridXMax + "\n" +
                            "YMin : " + se.GridYMin + "\n" +
                            "YMax : " + se.GridYMax + "\n" +
                            "VMean : " + se.GridVMean.ToString("0.0") + "\n" +
                            "VMin : " + se.GridVMin.ToString("0.0") + "\n" +
                            "VMax : " + se.GridVMax.ToString("0.0") + "\n" +
                            "Cols : " + se.MapNcols + "\n" +
                            "Rows : " + se.MapNrows + "\n" +
                            "Cellsize : " + se.MapCellsize);
        }

        // On worker thread so do our thing!
        void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Threading.Thread.Sleep(500);

            FileInfo fi = new FileInfo(se.Kb2dOutputFile);
            long lold = 0;
            // Your background task goes here
            for (int i = 0; i <= 3600; i++)
            {
                fi.Refresh();
                //MessageBox.Show(fi.Length.ToString());
                int i2 = Convert.ToInt32((((double)fi.Length) / (((double)se.NrPoints) * 40.0)) * 100.0);
                i2 = Math.Min(100, i2);
                // Report progress to 'UI' thread
                backgroundWorker2.ReportProgress(i2);
                // Simulate long task
                System.Threading.Thread.Sleep(1000);
                if (fi.Length == lold)
                {
                    cbgen.Progress("", 0, "Processing Kriging output");
                    //cbgen.Close();
                    //MessageBox.Show("Simulation completed\nCheck Output->Rep");
                    break;
                }
                else
                {
                    lold = fi.Length;
                }
            }
            //cbgen.Close();
        }
        // Back on the 'UI' thread so we can update the progress bar
        void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // The progress percentage is a property of e
            cbgen.Progress(" ", e.ProgressPercentage, "Kriging");
        }
        public void showMap(int mapType, int layerNr)
        {
            se.ErrorMessage = null;
            se.AvzFile = se.ResultFolderpath + "\\" + se.ProjectName + ".AVZ";
            se.SdzFile = se.ResultFolderpath + "\\" + se.ProjectName + ".SDZ";
            se.MapFile = se.TempFolderpath + "\\" + se.ProjectName + "_MAP.asc";
            //se.MapFile = se.ResultFolderpath + "\\" + se.ProjectName + "_MAP.asc";
            XYPointFile xyf = new XYPointFile();
            
            se.MapType = mapType;
            se.MapLayernr = layerNr;
            if (se.MapType < 1)
            {
                MessageBox.Show("Define Maptype first");
                return;
            }
            if (se.MapLayernr < 1 || se.MapLayernr > se.NrLayers)
            {
                MessageBox.Show("Layernr for Map invalid");
                return;
            }
            switch (se.MapType)
            {
                case Constants.MAP_TWT:
                    if (File.Exists(se.InputFileTWT))
                    {
                        gridFile = se.InputFileTWT;
                    }
                    else
                    {
                        gridFile = (string)se.AlInputFileTWT[se.MapLayernr-1];
                    }
                    gridType = "TWT";
                    break;
                case Constants.MAP_TWTDEV:
                    gridFile = (string)se.AlInputFileTWTdev[se.MapLayernr-1];
                    gridType = "TWTDEV";
                    break;
                case Constants.MAP_V:
                    gridFile = (string)se.AlInputFileV0[se.MapLayernr-1];
                    gridType = "V";
                    break;
                case Constants.MAP_VDEV:
                    gridFile = (string)se.AlInputFileVVNdev[se.MapLayernr-1];
                    gridType = "VDEV";
                    break;
                case Constants.MAP_Z:
                    gridFile = se.AvzFile;
                    gridType = "Z";
                    break;
                case Constants.MAP_ZDEV:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV";
                    break;
                case Constants.MAP_ZDEV_WELL:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV_WELL";
                    break;
                case Constants.MAP_WELL_BULL:
                    gridFile = se.SdzFile;
                    gridType = "WELL_BULL";
                    break;
                case Constants.MAP_ZDEV_WELL2:
                    gridFile = se.SdzFile;
                    gridType = "ZDEV_WELL2";
                    break;
                case Constants.MAP_RES_KRIG:
                    gridFile = se.AvzFile;
                    gridType = "RES_KRIG";
                    break;
                case Constants.MAP_Z_WELL:
                    gridFile = se.AvzFile;
                    gridType = "Z_WEll";
                    break;
            }
            se.MapXyzFile = gridFile;
            if (!File.Exists(gridFile))
            {
                MessageBox.Show("Map Inputgrid File " + gridFile + " does not exist");
                return;
            }
            se = xyf.getMapParams(se,gridFile);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            }
            // check for well controlpoints
            Directory.SetCurrentDirectory(se.TempFolderpath);
            //Directory.SetCurrentDirectory(se.ResultFolderpath);
            se.Kb2dGo = false;
            se.Kb2dParFile = "kb2d.par";
            se.Kb2dControlPointsFile = "kb2dcontrol.dat";
            se.Kb2dOutputFile = "kb2d.out";
            // if wellcontrolpoints exist create controlpoint file
            // and kb2d parameter file, run kb2d
            if ((File.Exists(se.WellLayerFile) && se.MapType==Constants.MAP_ZDEV_WELL) ||
                 se.MapType==Constants.MAP_Z_WELL ||
                 se.MapType==Constants.MAP_ZDEV_WELL2 ||
                 se.MapType==Constants.MAP_WELL_BULL ||
                 se.MapType==Constants.MAP_RES_KRIG)
            {
                se = xyf.saveKb2dWellLayerFile(sf, se);
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(se.ErrorMessage);
                    return;
                }
                if ((se.Kb2dGo && se.MapType == Constants.MAP_ZDEV_WELL) ||
                    (se.Kb2dGo && se.MapType == Constants.MAP_Z_WELL) ||
                    (se.Kb2dGo && se.MapType == Constants.MAP_ZDEV_WELL2) ||
                    (se.Kb2dGo && se.MapType == Constants.MAP_WELL_BULL) ||
                    (se.Kb2dGo && se.MapType == Constants.MAP_RES_KRIG))
                {
                    Kb2dParFile kpf = new Kb2dParFile();
                    se = kpf.saveKb2dParFile(se);
                    if (se.ErrorMessage != null)
                    {
                        MessageBox.Show(se.ErrorMessage);
                        return;
                    }
                    // run Kriging(KB2D)
                    //KB2D_VELSTO();
                    string kb2dexe = Application.StartupPath + "\\kb2d_velsto.exe";
                    cmd.Command = kb2dexe;
                    // catch run exited event
                    cmd.Exited += new CommandLineProcess.ExitedEventHandler(kb2d_Exited);
                    //se.CommandDone = false;
                    bool bSuccess = cmd.Start();
                    if (!bSuccess)
                    {
                        MessageBox.Show("Could not start Well Kriging\nanother Kriging run maybe active\nOtherwise contact support");
                        cmd.Exited -= new CommandLineProcess.ExitedEventHandler(kb2d_Exited);                    
                        return;
                    }
                    backgroundWorker2.RunWorkerAsync();
                    cbgen = new cBack();
                    cbgen.Show();
                    cbgen.Progress("", 0, "Kriging");
                    return;
                }
            }
            call_map();
        }

        private void call_map()
        {
            // Rest Map production seperate due to callback in case of Well Kriging
            // For Well Kriging make Dictionary
            if (se.Kb2dGo && (se.MapType == Constants.MAP_ZDEV_WELL ||
                              se.MapType == Constants.MAP_Z_WELL ||
                              se.MapType == Constants.MAP_ZDEV_WELL2 ||
                              se.MapType == Constants.MAP_WELL_BULL ||
                              se.MapType == Constants.MAP_RES_KRIG))
            {
                se = this.getDictKb2d(se);
                //Cursor.Current = Cursors.Default;                   
                if (se.ErrorMessage != null)
                {
                    MessageBox.Show(se.ErrorMessage);
                    return;
                }
            }

            //MessageBox.Show("Map file " + se.MapFile);
            Dictionary<Point,double> dictmap = new Dictionary<Point,double>();
            XYPointFile xyp1 = new XYPointFile();
            xyp1.createMapFile(se.MapFile, gridFile, se.MapLayernr, dictkb2d, ref se);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            } 
            //set variables for ZDEV_WELL(Map A) and Z_WELL map(Map B) ready fro combined map.
            if (se.MapType == Constants.MAP_ZDEV_WELL)
            {
                dictMapA = dictmap;
                se.MapAReady = true;
            }
            else if (se.MapType == Constants.MAP_Z_WELL)
            {
                dictMapB = dictmap;
                se.MapBReady = true;
            }
            // Show Map
            string textLayer;
            if (((String) se.AlLayername[se.MapLayernr-1]).Equals(""))
            {
                textLayer = se.MapLayernr.ToString();
            }
            else
            {
                textLayer = (String) se.AlLayername[se.MapLayernr-1];
            }
            string formText = se.ProjectName + " " + gridType + " layer " + textLayer;
            FormMap fmap = new FormMap(true, resWorkflow, new SelectDelegate(showRwfMap), se, formText);
            fmap.Show();
        }


        // Method to catch gslib KB2D_VELSTO exited event (and Show results).
        private void kb2d_Exited(object sender, EventArgs e)
        {
            cmd.Exited -= new CommandLineProcess.ExitedEventHandler(kb2d_Exited);
            if (cmd.ExitCode == 0)
            {
                cmd.Close();
                //cmd.Abort();
                                
                // the following is necessary for thread safe invoking
                // of the Map Form (from FormMain)
                // call_mapCallBack is a delegate
                if (this.InvokeRequired)
                {
                    call_mapCallback d = new call_mapCallback(call_map);
                    this.Invoke(d);
                }
                else
                {
                    /*MessageBox.Show("No Invoke");*/
                    call_map();
                }
            }
            else
            {
                MessageBox.Show("Well Kriging run failed");
                cmd.Close();
            }
            return;
        }

        // Method to read valid points from Kriging(KB2D) output in Dictionary
        // to be used for calibrating the Uncertainty map with kriged well variances.
        // Dictionary slkb2d is global.
        private SimulationEntity getDictKb2d(SimulationEntity se)
        {
            try
            {
                Directory.SetCurrentDirectory(se.TempFolderpath);
                string outf = se.TempFolderpath + "\\" + se.Kb2dOutputFile;
                //Directory.SetCurrentDirectory(se.ResultFolderpath);
                //string outf = se.ResultFolderpath + "\\" + se.Kb2dOutputFile;
                if (!File.Exists(outf))
                {
                    MessageBox.Show("Kriging output file " + outf + " does not exist");
                }
                TextReader readXY2 = new StreamReader(outf);
                Dictionary<Point, double> sl2 = new Dictionary<Point, double>();
                char[] delimiterChars = { ' ', '\t' };
                double v = 0.0;
                int iv = 0;
                string line = "";
                // determine correction x,y gridmin - min kriging output
                double xKrigMin = 99999999.0;
                double yKrigMin = 99999999.0;
                int xKrigCor = 0;
                int yKrigCor = 0;
                readXY2.ReadLine();
                readXY2.ReadLine();
                readXY2.ReadLine();
                readXY2.ReadLine();
                while ((line = readXY2.ReadLine()) != null)
                {
                    line = line.Replace(",", ".");
                    string[] words2 = line.Split(delimiterChars,
                                                StringSplitOptions.RemoveEmptyEntries);
                    xKrigMin = Math.Min(xKrigMin,parseDoubleString(words2[0]));
                    yKrigMin = Math.Min(yKrigMin,parseDoubleString(words2[1]));
                }
                if (xKrigMin <= se.MapXllcenter)
                {
                    xKrigCor = (int)((se.MapXllcenter - xKrigMin + 0.05) * 10.0);
                }
                else
                {
                    xKrigCor = (int)((se.MapXllcenter - xKrigMin - 0.05) * 10.0);
                }
                if (yKrigMin <= se.MapYllcenter)
                {
                    yKrigCor = (int)((se.MapYllcenter - yKrigMin + 0.05) * 10.0);
                }
                else
                {
                    yKrigCor = (int)((se.MapYllcenter - yKrigMin - 0.05) * 10.0);
                }
                readXY2.Close();
                TextReader readXY = new StreamReader(outf);
                // fill dictionary with kriging output
                double cbgen_max = (double)(se.MapNcols * se.MapNrows);
                int cbgen_show = (int)(cbgen_max / 100.0);
                int ibar = 0;
                int ibar2 = 0;
                int cbgen_perc = 0;
                // first read 4 headerlines;
                readXY.ReadLine();
                readXY.ReadLine();
                readXY.ReadLine();
                readXY.ReadLine();
                while ((line = readXY.ReadLine()) != null)
                {
                    ibar++;
                    ibar2++;
                    if (ibar2 > cbgen_show )
                    {
                        cbgen_perc = (int)( (((double)ibar) / cbgen_max) * 100.0) ;
                        cbgen_perc = Math.Min(100, cbgen_perc);
                        cbgen.Progress("",cbgen_perc,"Processing Kriging output");
                        ibar2 = 0;
                    }

                    line = line.Replace(",", ".");
                    Point xy1 = new Point();
                    string[] words = line.Split(delimiterChars,
                                                StringSplitOptions.RemoveEmptyEntries);
                    xy1.X = ((int) (parseDoubleString(words[0])*10.0)) + xKrigCor;
                    xy1.Y = ((int) (parseDoubleString(words[1])*10.0)) + yKrigCor;
                    // For dev map gather variance for avz map gather kriged interpolated value
                    if (se.MapType == Constants.MAP_ZDEV_WELL || se.MapType == Constants.MAP_ZDEV_WELL2
                        || se.MapType == Constants.MAP_WELL_BULL)
                    {
                        v = parseDoubleString(words[3]);
                        // Patch for values>1.0 (should be resolved inside gslib) 24/05 is resolved
                        if (v > 1.0)
                        {
                            v = 1.0;
                        }
                    }
                    else if (se.MapType == Constants.MAP_Z_WELL || se.MapType == Constants.MAP_RES_KRIG)
                    {
                        if (words[2].Contains("******"))
                        {
                            v = Constants.MAP_NODATA_DBL;
                        }
                        else
                        {
                            v = parseDoubleString(words[2]);
                        }
                    }
                    if (v > -999.0)
                    {
                        sl2.Add(xy1, v);
                        iv++;
                    }
                }
                dictkb2d = sl2;
                readXY.Close();
                cbgen.Close();
                return se;
            }
            catch (Exception ex)
            {
                se.ErrorMessage = ex.ToString();
                return se;
            }
        }

        
        #endregion

        #region Well tab

        private void rangeTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if ((!double.TryParse(rangeTextBox.Text,
                out newDouble) || newDouble < 0.0)
                && !(rangeTextBox.Text == "")
               )
            {
                e.Cancel = true;
                MessageBox.Show("Range must be positive number");
            }
        }

        private void rangeTextBox_Validated(object sender, EventArgs e)
        {
            if (rangeTextBox.Text != "")
            {
                rangeTextBox.Text = rangeTextBox.Text.Replace(",", ".");
                se.Kb2dRange = parseDoubleString(rangeTextBox.Text);
            }
            else
            {
                se.Kb2dRange = 0.0;
            }
        }

        private void wellLayerFileButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog of1 = new OpenFileDialog();
            of1.Filter = "All files (*.*)|*.*";
            of1.FilterIndex = 1;
            var mb_ret = of1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    se.WellLayerFile = of1.FileName;
                    se.SavedFile = false;
                    wellLayerFileTextBox.Text = of1.FileName;
                    break;
            }
        }

        private void wellLayerFileTextBox_DoubleClick(object sender, EventArgs e)
        {
            CommandLineProcess cmd = new CommandLineProcess();
            cmd.Command = "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
            cmd.Arguments = "\"" + wellLayerFileTextBox.Text.ToString() + "\"";
            bool bSuccess = cmd.Start();
            if (!bSuccess)
            {
                MessageBox.Show("Could not open file " + wellLayerFileTextBox.Text.ToString() + " \nContact Support");
                return;
            }
        }

        private void wellLayerFileTextBox_TextChanged(object sender, EventArgs e)
        {
            se.WellLayerFile = wellLayerFileTextBox.Text;
        }

        // Method to show ZDEV_Well Map (Map A)
        private void showmapfilewell_Button_Click(object sender, EventArgs e)
        {
            int mapType, layerNr;
            if (!File.Exists(se.WellLayerFile))
            {
                MessageBox.Show("**ERROR** Well Layer file not specified or existing");
                return;
            }
            se.WellResKrigingType = Constants.KRIGINGTYPE_ORDINARY;
            se.MapAReady = false;
            resWorkflow = false;
            layerNr = maplayerwell_ComboBox.SelectedIndex + 1;
            mapType = Constants.MAP_ZDEV_WELL;
            showMap(mapType, layerNr);
        }

        private void maplayerwell_ComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.MapALayernr = maplayerwell_ComboBox.SelectedIndex + 1;
        }

        
        private void Well_residuals_workflow_button_Click(object sender, EventArgs e)
        {
            int mapType, layerNr;
            resWorkflow = true;
            layerNr = well_tied_layer_comboboxb.SelectedIndex + 1;
            //MessageBox.Show("Callbacked model c1 range " + se.WellResVarioModel.ToString() + " " + se.WellResVarioC1.ToString() + " " + se.WellResVarioRange);
            mapType = Constants.MAP_Z;
            showMap(mapType, layerNr);

        }
        
        // Method to catch callback from Select(variogram) form to show Z_WELL map (Map B).
        private void showRwfMap(MapWinGIS.Shapefile sf1, SimulationEntity se2)
        {
            int mapType, layerNr;
            resWorkflow = false;
            sf = sf1;
            se = se2;
            se.MapBReady = false;
            layerNr = well_tied_layer_comboboxb.SelectedIndex + 1;
            //MessageBox.Show("Callbacked model c1 range " + se.WellResVarioModel.ToString() + " " + se.WellResVarioC1.ToString() + " " + se.WellResVarioRange);
            mapType = se.MapType;
            showMap(mapType, layerNr);
        }

        

        private void wellTvdMarkerFile_textbox_TextChanged(object sender, EventArgs e)
        {
            se.WellTvdMarkerFile = wellTvdMarkerTextBox.Text;
        }

        private void wellTvdMarkerFileButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog of1 = new OpenFileDialog();
            of1.Filter = "All files (*.*)|*.*";
            of1.FilterIndex = 1;
            var mb_ret = of1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    se.WellTvdMarkerFile = of1.FileName;
                    se.SavedFile = false;
                    wellTvdMarkerTextBox.Text = of1.FileName;
                    break;
            }
        }

        private void wellTvdMarkerFileTextBox_DoubleClick(object sender, EventArgs e)
        {
            CommandLineProcess cmd = new CommandLineProcess();
            cmd.Command = "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
            cmd.Arguments = "\"" + wellTvdMarkerTextBox.Text.ToString() + "\"";
            bool bSuccess = cmd.Start();
            if (!bSuccess)
            {
                MessageBox.Show("Could not open file " + wellTvdMarkerTextBox.Text.ToString() + " \nContact Support");
                return;
            }
        }
        
        

        private void well_tied_layer_comboboxb_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.MapBLayernr = well_tied_layer_comboboxb.SelectedIndex + 1;
        }
        
        private void bu_rwf_moreinfo_Click(object sender, EventArgs e)
        {
            if (lb_rwf_moreinfo.Visible == false)
            {
                lb_rwf_moreinfo.Visible = true;
                bu_rwf_moreinfo.Text = "Hide Info";
            }
            else
            {
                lb_rwf_moreinfo.Visible = false;
                bu_rwf_moreinfo.Text = "Info";
            }
        }
        
        private void bu_wellunc_moreinfo_Click(object sender, EventArgs e)
        {
            if (lb_wellunc_moreinfo.Visible == false)
            {
                lb_wellunc_moreinfo.Visible = true;
                bu_wellunc_moreinfo.Text = "Hide Info";
            }
            else
            {
                lb_wellunc_moreinfo.Visible = false;
                bu_wellunc_moreinfo.Text = "Info";
            }

        }

        #endregion

        

        


        
   
        #region Gridding
        private void inputXYZfileSelectbutton_Click(object sender, EventArgs e)
        {
            OpenFileDialog of1 = new OpenFileDialog();
            of1.Filter = "All files (*.*)|*.*";
            of1.FilterIndex = 1;
            var mb_ret = of1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    se.GriddingInFile = of1.FileName;
                    inputXYZfileTextbox.Text = of1.FileName;
                    XYPointFile xy1 = new XYPointFile();
                    se.ErrorMessage = null;
                    xy1.savedFiletoGridding(ref se);
                    if (se.ErrorMessage != null)
                    {
                        MessageBox.Show(se.ErrorMessage);
                        return;
                    }
                    break;
            }
        }

        private void inputXYZfileViewButton_Click(object sender, EventArgs e)
        {
            try
            {
                TextReader readInputFile;
                readInputFile = new StreamReader(inputXYZfileTextbox.Text);
                string line = readInputFile.ReadLine();
                if (line.Contains(Constants.SAVED_DEPTH_FILE_STRING))
                {
                    MessageBox.Show("Cannot View this filetype");
                    return;
                }
                else
                {
                    griddingViewFiles(inputXYZfileTextbox.Text);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error Viewing file");
            }
        }

        private void griddingViewFiles(string gridFile)
        {
            se.ErrorMessage = null;
            se.Kb2dGo = false;
            resWorkflow = false;
            se.MapType = Constants.MAP_GENXYZ;
            se.MapXyzFile = gridFile;
            
            se.MapFile = se.TempFolderpath + "\\" + se.ProjectName + "_MAP.asc";
            XYPointFile xyf = new XYPointFile();
            string gridType = "";
            //MessageBox.Show(se.MapType.ToString() + " mt ln " + se.MapLayernr.ToString());
            
            gridType = "XYZ file";
            if (!File.Exists(gridFile))
            {
                MessageBox.Show("Map Inputgrid File " + gridFile + " does not exist");
                return;
            }
            se = xyf.getMapParams(se, gridFile);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            }
            //MessageBox.Show("Map file " + se.MapFile);
            Dictionary<Point, double> slmap = new Dictionary<Point, double>();
            XYPointFile xyp1 = new XYPointFile();
            xyp1.createMapFile(se.MapFile, gridFile, 1, dictkb2d, ref se);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(se.ErrorMessage);
                return;
            }
            string formText = gridType + " " + gridFile;
            FormMap fmap = new FormMap(true, resWorkflow, new SelectDelegate(showRwfMap),se,formText);
            fmap.Show();
        }

        private void selGridRefButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog of1 = new OpenFileDialog();
            of1.Filter = "All files (*.*)|*.*";
            of1.FilterIndex = 1;
            var mb_ret = of1.ShowDialog();
            switch (mb_ret)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    //se.WellLayerFile = of1.FileName;
                    //se.SavedFile = false;
                    XYPointFile xyf = new XYPointFile();
                    se = xyf.getMapParams(se, of1.FileName);
                    xMinTextBox.Text = se.MapXllcenter.ToString();
                    xMaxTextBox.Text = (se.MapXllcenter + (se.MapNcols * se.MapCellsize)).ToString();
                    yMinTextBox.Text = se.MapYllcenter.ToString();
                    yMaxTextBox.Text = (se.MapYllcenter + (se.MapNrows * se.MapCellsize)).ToString();
                    intervalTextBox.Text = se.MapCellsize.ToString();
                    se.GridXMin = se.MapXllcenter;
                    se.GridXMax = se.MapXllcenter + (se.MapNcols * se.MapCellsize);
                    se.GridYMin = se.MapYllcenter;
                    se.GridYMax = se.MapYllcenter + (se.MapNrows * se.MapCellsize);
                    se.GridInterval = se.MapCellsize;
                    break;
            }
        }

        private void xMinTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(xMinTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("XMin must be Numeric");
            }
        }
        
        private void xMinTextBox_Validated(object sender, EventArgs e)
        {
            if (xMinTextBox.Text != "")
            {
                xMinTextBox.Text = xMinTextBox.Text.Replace(",", ".");
                se.GridXMin = parseDoubleString(xMinTextBox.Text);
            }
            else
            {
                se.GridXMin = 0.0;
            }
        }
       
        private void xMaxTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(xMaxTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("XMax must be Numeric");
            }
        }
        
        private void xMaxTextBox_Validated(object sender, EventArgs e)
        {
            if (xMaxTextBox.Text != "")
            {
                xMaxTextBox.Text = xMaxTextBox.Text.Replace(",", ".");
                se.GridXMax = parseDoubleString(xMaxTextBox.Text);
            }
            else
            {
                se.GridXMax = 0.0;
            }
        }

        private void yMinTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(yMinTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("YMin must be Numeric");
            }
        }

        private void yMinTextBox_Validated(object sender, EventArgs e)
        {
            if (yMinTextBox.Text != "")
            {
                yMinTextBox.Text = yMinTextBox.Text.Replace(",", ".");
                se.GridYMin = parseDoubleString(yMinTextBox.Text);
            }
            else
            {
                se.GridYMin = 0.0;
            }
        }

        private void yMaxTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(yMaxTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("YMax must be Numeric");
            }
        }

        private void yMaxTextBox_Validated(object sender, EventArgs e)
        {
            if (yMaxTextBox.Text != "")
            {
                yMaxTextBox.Text = yMaxTextBox.Text.Replace(",", ".");
                se.GridYMax = parseDoubleString(yMaxTextBox.Text);
            }
            else
            {
                se.GridYMax = 0.0;
            }
        }

        private void intervalTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(intervalTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("Interval must be Numeric");
            }
        }

        private void intervalTextBox_Validated(object sender, EventArgs e)
        {
            if (intervalTextBox.Text != "")
            {
                intervalTextBox.Text = intervalTextBox.Text.Replace(",", ".");
                se.GridInterval = parseDoubleString(intervalTextBox.Text);
            }
            else
            {
                se.GridInterval = 0.0;
            }
        }

        private void outputXYZbutton_Click(object sender, EventArgs e)
        {
            SaveFileDialog sf1 = new SaveFileDialog();
            sf1.Filter = "All files (*.*)|*.*";
            sf1.FilterIndex = 1;
            var mb_ret2 = sf1.ShowDialog();
            switch (mb_ret2)
            {
                case DialogResult.Cancel:
                    break;
                default:
                    se.GriddingOutFile = sf1.FileName;
                    outputXYZfileTextBox.Text = sf1.FileName;
                    break;
            }
        }

        private void outputXYZviewButton_Click(object sender, EventArgs e)
        {
            griddingViewFiles(outputXYZfileTextBox.Text);
        }

        private void griddingTypeCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            se.GriddingType = griddingTypeCB.SelectedIndex + 1;
            switch (se.GriddingType)
            {
                case Constants.GRIDDINGTYPE_TRIANG:
                    searchRadiuslabel.Hide();
                    searchRadiusTextBox.Hide();
                    break;
                case Constants.GRIDDINGTYPE_NEARNEIGH:
                    searchRadiuslabel.Show();
                    searchRadiusTextBox.Show();
                    searchRadiusTextBox.Text = se.GriddingSearchRadius.ToString();
                    break;
                case Constants.GRIDDINGTYPE_CONTCURV:
                    searchRadiuslabel.Show();
                    searchRadiusTextBox.Show();
                    searchRadiusTextBox.Text = se.GriddingSearchRadius.ToString();
                    break;
            }
        }

        private void searchRadiusTextBox_Validating(object sender, CancelEventArgs e)
        {
            double newDouble;
            if (!double.TryParse(searchRadiusTextBox.Text,
                out newDouble))
            {
                e.Cancel = true;
                MessageBox.Show("Search Radius must be Numeric");
            }
        }

        private void searchRadiusTextBox_Validated(object sender, EventArgs e)
        {
            if (searchRadiusTextBox.Text != "")
            {
                searchRadiusTextBox.Text = searchRadiusTextBox.Text.Replace(",", ".");
                se.GriddingSearchRadius = parseDoubleString(searchRadiusTextBox.Text);
            }
            else
            {
                se.GriddingSearchRadius = 0.0;
            }
        }

        private void runGriddingButton_Click(object sender, EventArgs e)
        {
            /*if (se.ResultFolderpath.Length == 0)
            {
                MessageBox.Show("First specify Result Folder in General tab");
                return;
            }*/
            Directory.SetCurrentDirectory(se.TempFolderpath);
            if (se.GriddingInFile.Length == 0 ||
                 se.GriddingOutFile.Length == 0 ||
                 xMinTextBox.Text.Equals("") ||
                 xMaxTextBox.Text.Equals("") ||
                 yMinTextBox.Text.Equals("") ||
                 yMaxTextBox.Text.Equals("") ||
                 intervalTextBox.Text.Equals("") ||
                 se.GriddingType == 0)
            {
                MessageBox.Show("Input for gridding incomplete");
                return;
            }
            
            se.RunGmtFile = se.TempFolderpath + "\\" + "RUNGMT.BAT";
            // GMT executabels and shr directory
            string triangulateexe = "triangulate";
            string nearneighborexe = "nearneighbor";
            string grd2xyzexe = "grd2xyz";
            string surfaceexe = "surface";
            string GMTshr = Application.StartupPath + "\\GMT\\share";
            string GMTbin = Application.StartupPath + "\\GMT\\bin";
            se.GmtLog_gr = se.TempFolderpath + "\\" + "GMT_gr.LOG";
            
            RunGMTFile rg = new RunGMTFile();
            se.ErrorMessage = rg.saveRunGMTFile(se,triangulateexe,
                nearneighborexe,grd2xyzexe,surfaceexe,GMTshr,GMTbin);
            if (se.ErrorMessage != null)
            {
                MessageBox.Show(this, se.ErrorMessage, "**Error**",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //cmd is global CommandlineProcess variable to be shared with callback  
            cmd.Command = se.RunGmtFile;
            cmd.Arguments = " > " + "\"" + se.GmtLog_gr + "\"";
            // catch run exited event
            cmd.Exited += new CommandLineProcess.ExitedEventHandler(runGMT_Exited);
            Cursor.Current = Cursors.WaitCursor; 
            outputXYZviewButton.Enabled = false;
            gmtlogButton.Enabled = false;
            bool bSuccess = cmd.Start();
            if (!bSuccess)
            {
                MessageBox.Show("Could not start Gridding\nContact Support");
                cmd.Exited -= new CommandLineProcess.ExitedEventHandler(runGMT_Exited);
                return;
            }
            return;
        }


        private void runGMT_Exited(object sender, EventArgs e)
        {
            cmd.Exited -= new CommandLineProcess.ExitedEventHandler(runGMT_Exited);
            if (cmd.ExitCode == 0)
            {
                cmd.Close();
            }
            else
            {
                 MessageBox.Show("GMT Gridding failed, View Log file for details\r\nNote there is a unresolved issue\r\n" +
                "when running with changed input but same output file\r\nthe run fails, it is advised to select " +
                "a different output file"); 
                cmd.Close();
            }
            outputXYZviewButton.Enabled = true;
            gmtlogButton.Enabled = true;
            Cursor.Current = Cursors.Default;
            return;
        }


        private void gmtURLButton_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start("chrome.exe", "www.soest.hawaii.edu/gmt");
            }
            catch (Exception ex)
            {
                try
                {
                    System.Diagnostics.Process.Start("iexplore.exe","www.soest.hawaii.edu/gmt");

                }
                catch (Exception ex2)
                {
                    MessageBox.Show("Need Chrome or Internet Explorer this way \n");
                }
            } 
        }

        private void gmtlogBbutton_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("notepad.exe", se.GmtLog_gr);
        }

        private void bu_grid_moreinfo_Click(object sender, EventArgs e)
        {
            if (lb_grid_moreinfo.Visible == false)
            {
                lb_grid_moreinfo.Visible = true;
                bu_grid_moreinfo.Text = "Hide Info";
            }
            else
            {
                lb_grid_moreinfo.Visible = false;
                bu_grid_moreinfo.Text = "Info";
            }
        }
        #endregion


        // Method to parse with both decimal separators
        public double parseDoubleString(string sd)
        {
            var currentCulture = System.Globalization.CultureInfo.InstalledUICulture;
            var numberFormat = (System.Globalization.NumberFormatInfo)
            currentCulture.NumberFormat.Clone();
            numberFormat.NumberDecimalSeparator = ".";
            double number;
            bool succeeded = double.TryParse(sd, System.Globalization.NumberStyles.Any, numberFormat, out number);
            if (succeeded)
            {
                return number;
            }
            else
            {
                numberFormat.NumberDecimalSeparator = ",";
                bool succeeded2 = double.TryParse(sd, System.Globalization.NumberStyles.Any, numberFormat, out number);
                if (succeeded2)
                {
                    return number;
                }
                else
                {
                    MessageBox.Show("**ERROR** Invalid Number");
                    return -99999.9;
                }
            }
        }

        
        


        

        

        

        

        

        

        

        

        


    }
}
